package org.dev.vlp.service.impl;

import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.dev.vlp.constants.LanguageEnum;
import org.dev.vlp.entity.*;
import org.dev.vlp.exception.ApiException;
import org.dev.vlp.mapper.*;
import org.dev.vlp.service.LearnRecordService;
import org.dev.vlp.service.StatisticsService;
import org.dev.vlp.vo.StatisticsVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
* @author 86184
* @description 针对表【vlp_learn_record】的数据库操作Service实现
* @createDate 2023-01-23 18:11:12
*/
@Service
public class LearnRecordServiceImpl extends ServiceImpl<LearnRecordMapper, LearnRecord>
    implements LearnRecordService{

    @Autowired
    private StatisticsService statisticsService;
    @Autowired
    private StatisticsMapper statisticsMapper;
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private DailyRecordMapper dailyRecordMapper;

    @Autowired
    private LearnRecordMapper learnRecordMapper;

//    @Autowired
//    private WordBookMapper wordBookMapper;

    @Autowired
    private WordMapper wordMapper;

    private int[] memoryCircle = {1,2,4,7,15};

    @Override
    public List<Word> getNewWords(int uid,int needCount) {
        int lan = statisticsService.getLan(uid);
        LanguageEnum languageEnum = LanguageEnum.get(lan);
//        String wordBookTable = languageEnum.getWordBookTableEnum().getTableName();
        String wordTable = languageEnum.getWordTableEnum().getTableName();

        // 获取现在所背的词书
        QueryWrapper<Statistics> statisticsQueryWrapper = new QueryWrapper<>();
        statisticsQueryWrapper.eq("user_id",uid)
                .eq("lan_id",lan)
                .orderByDesc("gmt_modified")
                .last("limit 1");
        Statistics statistics = statisticsMapper.selectOne(statisticsQueryWrapper);
        Integer bookId = statistics.getBookId();
        Integer wordNumber = statistics.getWordNumber();
        List<Word> bookWordByPage = wordMapper.getBookWordByPage(bookId.longValue(), wordNumber, needCount, wordTable);

        return bookWordByPage;
    }


    @Override
    public StatisticsVO getNeedLearnAndReview(int uid) {
        Date todayDate = DateUtil.parseDate(DateUtil.today());
        int lan = statisticsService.getLan(uid);
        // 获取用户的每日单词数
        User user = userMapper.selectById(uid);
        Integer groupSize = user.getGroupSize();

        // 获取用户今日的学习记录
        QueryWrapper<DailyRecord> dailyRecordQueryWrapper = new QueryWrapper<>();
        dailyRecordQueryWrapper.eq("lan_id",lan)
                .eq("user_id",uid)
                .eq("gmt_create",todayDate);
        DailyRecord dailyRecord = dailyRecordMapper.selectOne(dailyRecordQueryWrapper);
        if(dailyRecord!=null){
            groupSize=groupSize-dailyRecord.getLearnCount();
        }
        int needReviewWordCount = learnRecordMapper.findNeedReviewWordCount(uid, lan);
        StatisticsVO res = new StatisticsVO();
        res.setUnlearn(groupSize);
        res.setReview(needReviewWordCount);

        return res;
    }

    @Override
    public List<Word> getNeedReviewWords(int uid) {
        int lan = statisticsService.getLan(uid);
        LanguageEnum languageEnum = LanguageEnum.get(lan);

        String wordTable = languageEnum.getWordTableEnum().getTableName();
        int needReviewWordCount = learnRecordMapper.findNeedReviewWordCount(uid,lan);
        List<Integer> reviewWordsID = learnRecordMapper.findNeedReviewWordsID(uid,lan);
        List<Word> reviewWords = new ArrayList<>(needReviewWordCount);
        for(Integer i : reviewWordsID){
            Word targetWord = wordMapper.getWord(i,wordTable);
            reviewWords.add(targetWord);
        }
        return reviewWords;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void learnNewWord(int uid,List<Integer> wordIds){
        // 批量插入单词学习记录
        Date todayDate = DateUtil.parseDate(DateUtil.today());
        List<LearnRecord> learnRecords = new ArrayList<>();
        int length = wordIds.size();
        int lan = statisticsService.getLan(uid);
        for (int i = 0; i < length; i++) {
            LearnRecord learnRecord = new LearnRecord();
            learnRecord.setUserId(uid);
            learnRecord.setLanId(lan);
            learnRecord.setWordId(wordIds.get(i));
            learnRecord.setPhase(1);
            learnRecord.setGmtCreate(new Date());
            learnRecord.setNextMemoryTime(DateUtil.offsetDay(todayDate,memoryCircle[0]));
            learnRecords.add(learnRecord);
        }
        List<LearnRecord> existingRecords = learnRecordMapper.checkExistence(learnRecords);
        if (!existingRecords.isEmpty()) {
            throw new ApiException("批量插入失败，存在重复记录！");
        }

        int result = learnRecordMapper.batchInsert(learnRecords);
        if (result != learnRecords.size()) {
            throw new ApiException("批量插入失败！");
        }
//        learnRecordMapper.insertBatchSomeColumn(learnRecords);
        // 每日记录
        LambdaQueryWrapper<DailyRecord> lambdaQueryWrapper = Wrappers.lambdaQuery();
        DailyRecord dateRecord = dailyRecordMapper.selectOne(lambdaQueryWrapper
                .eq(DailyRecord::getUserId,uid)
                .eq(DailyRecord::getLanId,lan)
                .eq(DailyRecord::getGmtCreate, todayDate));
        if(dateRecord == null){
            //如果当天没有学习记录，则新增学习记录
            DailyRecord newDateRecord = new DailyRecord();
            newDateRecord.setUserId(uid);
            newDateRecord.setLanId(lan);
            newDateRecord.setGmtCreate(todayDate);
            // 学习时长
            newDateRecord.setLearnCount(length);
            newDateRecord.setReviewCount(0);
            dailyRecordMapper.insert(newDateRecord);
        }
        else{ //当天有学习记录则将已学习单词数+1
            dateRecord.setLearnCount(dateRecord.getLearnCount()+length);
            dailyRecordMapper.update(dateRecord,lambdaQueryWrapper);
        }
        // 词书记录更新，方便选单词
        QueryWrapper<Statistics> statisticsQueryWrapper = new QueryWrapper<>();
        statisticsQueryWrapper.eq("user_id",uid)
                .eq("lan_id",lan)
                .orderByDesc("gmt_modified")
                .last("limit 1");
        Statistics statistics = statisticsMapper.selectOne(statisticsQueryWrapper);
        if(statistics==null){
            throw new ApiException("词书记录不存在");
        }else{
            statistics.setWordNumber(statistics.getWordNumber()+length);
            statisticsMapper.updateById(statistics);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void reviewOldWord(List<Integer> wordIds,List<Integer> reviews,int uid){
        Date todayDate = DateUtil.parseDate(DateUtil.today());
        int length = wordIds.size();
        int lan = statisticsService.getLan(uid);
        int grasp=0;
        for(int i=0;i<length;i++){
            LambdaQueryWrapper<LearnRecord> lambdaQueryWrapper = Wrappers.lambdaQuery();
            if(reviews.get(i) ==1){
                LearnRecord mmryRecord = learnRecordMapper.selectOne(lambdaQueryWrapper
                        .eq(LearnRecord::getUserId, uid)
                        .eq(LearnRecord::getLanId,lan)
                        .eq(LearnRecord::getWordId, wordIds.get(i)));
                int index = mmryRecord.getPhase();
                if(index < 5){
                    Date nextMmryTime = DateUtil.offsetDay(todayDate,memoryCircle[index]);
                    mmryRecord.setNextMemoryTime(nextMmryTime);
                    mmryRecord.setPhase(mmryRecord.getPhase()+1);
                    learnRecordMapper.update(mmryRecord,lambdaQueryWrapper);
                }else{
                    //phase = 5时，下次不用再复习了
                    mmryRecord.setPhase(index+1);
                    learnRecordMapper.update(mmryRecord,lambdaQueryWrapper);
                    grasp+=1;
                }
            }
        }
        // 词书记录更新
        QueryWrapper<Statistics> statisticsQueryWrapper = new QueryWrapper<>();
        statisticsQueryWrapper.eq("user_id",uid)
                .eq("lan_id",lan)
                .orderByDesc("gmt_modified")
                .last("limit 1");
        Statistics statistics = statisticsMapper.selectOne(statisticsQueryWrapper);
        if(statistics==null){
            throw new ApiException("词书记录不存在");
        }else{
            statistics.setGraspNumber(statistics.getGraspNumber()+grasp);
            statisticsMapper.updateById(statistics);
        }

        LambdaQueryWrapper<DailyRecord> dateRecordWrapper = Wrappers.lambdaQuery();
        DailyRecord dateRecord = dailyRecordMapper.selectOne(dateRecordWrapper
                .eq(DailyRecord::getUserId,uid)
                .eq(DailyRecord::getLanId,lan)
                .eq(DailyRecord::getGmtCreate, todayDate));
        if(dateRecord == null){
            //如果当天没有学习记录，则新增学习记录
            DailyRecord newDateRecord = new DailyRecord();
            newDateRecord.setUserId(uid);
            newDateRecord.setLanId(lan);
            newDateRecord.setGmtCreate(todayDate);
            newDateRecord.setLearnCount(0);
            newDateRecord.setReviewCount(length);
            dailyRecordMapper.insert(newDateRecord);
        }
        else{
            //当天有学习记录则将已复习单词数+1
            dateRecord.setReviewCount(dateRecord.getReviewCount()+length);
            dailyRecordMapper.update(dateRecord,dateRecordWrapper);
        }

    }
}




